using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using RAG.Application.Interfaces;
using RAG.Application.Dtos;

namespace RAG.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class DocumentController : ControllerBase
{
    private readonly IAppDocumentService _documentService;

    public DocumentController(IAppDocumentService documentService)
    {
        _documentService = documentService;
    }

    /// <summary>
    /// 上传文档
    /// </summary>
    [HttpPost("upload")]
    public async Task<IActionResult> UploadDocument([FromForm] UploadDocumentDto dto)
    {
        try
        {
            // 从JWT中获取用户ID
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            dto.UserId = userId;
            var result = await _documentService.UploadDocumentAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"上传文档时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 获取文档列表
    /// </summary>
    [HttpGet]
    public async Task<IActionResult> GetDocuments([FromQuery] Guid? knowledgeBaseId = null)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            var result = await _documentService.GetDocumentsAsync(userId, knowledgeBaseId);
            return Ok(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"获取文档列表时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 获取文档详情
    /// </summary>
    [HttpGet("{documentId}")]
    public async Task<IActionResult> GetDocument(Guid documentId)
    {
        try
        {
            var result = await _documentService.GetDocumentAsync(documentId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"获取文档详情时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 删除文档
    /// </summary>
    [HttpDelete("{documentId}")]
    public async Task<IActionResult> DeleteDocument(Guid documentId)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            var result = await _documentService.DeleteDocumentAsync(documentId, userId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"删除文档时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 搜索文档
    /// </summary>
    [HttpPost("search")]
    public async Task<IActionResult> SearchDocuments([FromBody] SearchDocumentsDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            dto.UserId = userId;
            var result = await _documentService.SearchDocumentsAsync(dto);
            return Ok(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"搜索文档时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 批量上传文档
    /// </summary>
    [HttpPost("batch-upload")]
    public async Task<IActionResult> BatchUploadDocuments([FromForm] BatchUploadDocumentsDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            dto.UserId = userId;
            var result = await _documentService.BatchUploadDocumentsAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"批量上传文档时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 更新文档基本信息
    /// </summary>
    [HttpPut("{documentId}")]
    public async Task<IActionResult> UpdateDocument(Guid documentId, [FromBody] UpdateDocumentDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            dto.DocumentId = documentId;
            dto.UserId = userId;
            var result = await _documentService.UpdateDocumentAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"更新文档时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 更新文档权限
    /// </summary>
    [HttpPut("{documentId}/permissions")]
    public async Task<IActionResult> UpdateDocumentPermissions(Guid documentId, [FromBody] UpdateDocumentPermissionsDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            dto.DocumentId = documentId;
            dto.UserId = userId;
            var result = await _documentService.UpdateDocumentPermissionsAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"更新文档权限时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 获取文档的文档块列表
    /// </summary>
    [HttpGet("{documentId}/chunks")]
    public async Task<IActionResult> GetDocumentChunks(Guid documentId)
    {
        try
        {
            var result = await _documentService.GetDocumentChunksAsync(documentId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"获取文档块时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 重新处理文档（重新分块和向量化）
    /// </summary>
    [HttpPost("{documentId}/reprocess")]
    public async Task<IActionResult> ReprocessDocument(Guid documentId)
    {
        try
        {
            var result = await _documentService.ReprocessDocumentAsync(documentId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"重新处理文档时发生错误: {ex.Message}" });
        }
    }

    /// <summary>
    /// 下载文档
    /// </summary>
    [HttpGet("download/{documentId}")]
    public async Task<IActionResult> DownloadDocument(Guid documentId)
    {
        try
        {
            // 从JWT中获取用户ID
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(new { code = 400, message = "无法获取用户信息" });
            }

            var result = await _documentService.DownloadDocumentAsync(documentId, userId);
            if (result.Code == 200 && result.Data is DocumentDownloadInfoDto ok)
            {
                if (System.IO.File.Exists(ok.FilePath))
                {
                    var fileStream = new System.IO.FileStream(ok.FilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
                    return File(fileStream, ok.ContentType, ok.FileName);
                }
            }

            // 原文件不存在或获取信息失败，尝试基于分块生成纯文本作为降级下载
            var fallback = await _documentService.GenerateTextFromChunksAsync(documentId, userId);
            if (fallback != null)
            {
                var (bytes, contentType, fileName) = fallback.Value;
                return File(bytes, contentType, fileName);
            }

            // 仍然失败，返回结果错误或 404
            if (result.Code == 404)
            {
                return NotFound(new { code = 404, message = "文件不存在" });
            }
            return BadRequest(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { code = 500, message = $"下载文档时发生错误: {ex.Message}" });
        }
    }
}
